from pycparser import c_ast

def _parse_decl_kwargs(**kwargs):
    quals = []
    if 'quals' in kwargs:
        quals = kwargs['quals']
    align = None
    if 'align' in kwargs:
        align = kwargs['align']
    storage = []
    if 'storage' in kwargs:
        storage = kwargs['storage']
    funcspec = []
    if 'funcspec' in kwargs:
        funcspec = kwargs['funcspec']
    init = None
    if 'init' in kwargs:
        init = kwargs['init']
    bitsize = None
    if 'bitsize' in kwargs:
        bitsize = kwargs['bitsize']
    return quals, align, storage, funcspec, init, bitsize

def create_variable_decl(name, type_name, **kwargs):
    quals, align, storage, funcspec, init, bitsize = _parse_decl_kwargs(**kwargs)
    if isinstance(init, str):
        init = c_ast.Constant(type_name, init)
    """创建变量声明节点"""
    return c_ast.Decl(
        name=name,
        quals=quals,
        storage=storage,
        funcspec=funcspec,
        align=align,
        type=c_ast.TypeDecl(
            declname=name,
            quals=quals,
            align=align,
            type=c_ast.IdentifierType([type_name])
        ),
        init=init,
        bitsize=bitsize
    )

def create_ptr_decl(name, type_name, **kwargs):
    quals, align, storage, funcspec, init, bitsize = _parse_decl_kwargs(**kwargs)
    if isinstance(init, str):
        init = c_ast.Constant(type_name, init)
    ptr_quals = []
    if 'ptr_quals' in kwargs:
        ptr_quals = kwargs['ptr_quals']
    """创建变量声明节点"""
    return c_ast.Decl(
        name=name,
        quals=quals,
        storage=storage,
        funcspec=funcspec,
        align=align,
        type=c_ast.PtrDecl(
            quals=ptr_quals,
            type=c_ast.TypeDecl(
                declname=name,
                quals=quals,
                align=align,
                type=c_ast.IdentifierType([type_name])
            )
        ),
        init=init,
        bitsize=bitsize
    )
    
def create_function_decl(name, return_type, params, **kwargs):
    quals, align, storage, funcspec, init, bitsize = _parse_decl_kwargs(**kwargs)
    if len(params) and params[-1] == '...':
        params[-1] = c_ast.EllipsisParam()
    """创建函数声明节点"""
    return c_ast.Decl(
        name=name,
        quals=quals,
        storage=storage,
        funcspec=funcspec,
        align=align,
        type=c_ast.FuncDecl(
            args=c_ast.ParamList(params),
            type=c_ast.TypeDecl(
                declname=name,
                quals=quals,
                align=align,
                type=c_ast.IdentifierType([return_type])
            )
        ),
        init=init,
        bitsize=kwargs
    )

def create_function_def(body=None, **kwargs):
    if 'name' in kwargs and 'return_type' in kwargs and 'params' in kwargs:
        name = kwargs['name']
        return_type = kwargs['return_type']
        params = kwargs['params']
        decl = create_function_decl(name, return_type, params, kwargs=kwargs)
    elif 'func_decl' in kwargs:
        decl = kwargs['func_decl']
    else:
        raise ValueError('没有创建函数定义的足够信息')
    if not body:
        body = c_ast.Compound(block_items=[])
    if isinstance(body, list):
        body = c_ast.Compound(block_items=body)
    """创建函数定义节点"""
    return c_ast.FuncDef(
        decl=decl,
        param_decls=None,
        body=body
    )
    